﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Xml.Schema;
using System.Web;
using System.IO;
using System.IO.Compression;
using Microsoft.CSharp;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;

namespace AppEntity
{
    public partial class Common
    {
        public partial class Utility
        {
            public static Random Random = new Random();

            public static string GetNowTime()
            {
                return System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz");
            }
            public static DateTime Now()
            {
                return System.DateTime.Now;
            }
            public static string MD5(string txt)
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txt, "MD5").ToUpper();
            }
            public static string SHA1(string txt)
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txt, "SHA1").ToUpper();
            }
            public static string GetNowTime(string format)
            {
                return System.DateTime.Now.ToString(format);
            }
            public static string GetNowTime(DateTime dt, string format)
            {
                return dt.ToString(format);
            }
            public static string GetNowTime(DateTime dt)
            {
                string str = dt.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz");
                return str;
            }
            public static string GetTimeStamp()
            {
                DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                DateTime dtNow = DateTime.Parse(DateTime.Now.ToString());
                TimeSpan toNow = dtNow.Subtract(dtStart);
                string timeStamp = toNow.Ticks.ToString();
                return timeStamp.Substring(0, timeStamp.Length - 7);
            }
            public static DateTime GetDateTimeByTimeStamp(string timestamp)
            {
                DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                long lTime = long.Parse(timestamp + "0000000");
                TimeSpan toNow = new TimeSpan(lTime);
                DateTime dtResult = dtStart.Add(toNow);
                return dtResult;
            }
            public static DateTime GetDateTimeByString(string datetime)
            {
                if (datetime.Length == 10 && datetime.IndexOf("-") == 4 && datetime.LastIndexOf("-") == 7)
                {
                    datetime += "T00:00:00.000+08:00";
                }
                if (datetime.Length != 29)
                {
                    throw new NullReferenceException("“" + datetime + "”:传入的时间字符串错误，长度必须为29。例如：2010-05-09T08:06:01.123+08:00");
                }

                DateTime dt = System.DateTime.ParseExact(datetime, "yyyy-MM-ddTHH:mm:ss.fffzzz", new System.Globalization.CultureInfo("zh-CN", true));
                return dt;
            }
            public static DateTime GetDateTimeByString(string datetime, string timezone)
            {
                DateTime dt = GetDateTimeByString(datetime);
                if (timezone.Length == 3 && timezone != "+08")
                {
                    int addhour = 0;
                    try
                    {
                        addhour = -8 + System.Convert.ToInt32(timezone);
                    }
                    catch (Exception ex)
                    {
                        addhour = 0;
                    }
                    dt = dt.AddHours(addhour);
                }
                return dt;
            }
            public static string GUID()
            {
                return System.Guid.NewGuid().ToString().ToUpper();
            }

            private static StringBuilder ValidateError = new StringBuilder();
            /// <summary>
            /// 验证Xml数据，返回错误信息。如果验证通过，返回空字符串。
            /// </summary>
            /// <param name="XmlFile">Xml文件路径</param>
            /// <param name="XsdFile">Xsd文件路径</param>
            /// <returns></returns>        
            public static string SchemaValidate(string XmlFile, string XsdFile, bool OutputXmlFormat)
            {
                ValidateError.Remove(0, ValidateError.Length);
                XmlReader reader = null;
                XmlReaderSettings setting = new XmlReaderSettings();

                if (OutputXmlFormat == true)
                {
                    setting.ValidationEventHandler += new ValidationEventHandler(Utility.ValidationEventHandlerDetail);
                }
                else
                {
                    setting.ValidationEventHandler += new ValidationEventHandler(Utility.ValidationEventHandlerMessage);
                }

                setting.ValidationType = ValidationType.Schema;
                setting.Schemas.Add(null, XmlReader.Create(XsdFile));
                reader = XmlReader.Create(XmlFile, setting);
                try
                {
                    while (reader.Read())
                    { }
                    reader.Close();
                }
                catch (XmlException e)
                {
                    reader.Close();
                }
                string html = "";
                if (OutputXmlFormat == true)
                {
                    html = "<?xml version=\"1.0\" encoding=\"utf-8\"?><root>" + ValidateError.ToString() + "</root>";
                }
                else
                {
                    html = ValidateError.ToString();
                }
                ValidateError.Remove(0, ValidateError.Length);
                return html;
            }
            public static string SchemaValidate(XmlDocument dom, string XsdFile, bool OutputXmlFormat)
            {
                ValidateError.Remove(0, ValidateError.Length);
                XmlReader xsdreader = XmlReader.Create(XsdFile);
                XmlReader reader = null;

                XmlReaderSettings setting = new XmlReaderSettings();
                if (OutputXmlFormat == true)
                {
                    setting.ValidationEventHandler += new ValidationEventHandler(Utility.ValidationEventHandlerDetail);
                }
                else
                {
                    setting.ValidationEventHandler += new ValidationEventHandler(Utility.ValidationEventHandlerMessage);
                }
                setting.ValidationType = ValidationType.Schema;
                setting.Schemas.Add(null, xsdreader);
                XmlNodeReader nodeReader = new XmlNodeReader(dom);
                reader = XmlReader.Create(nodeReader, setting);
                try
                {
                    while (reader.Read())
                    { }
                    reader.Close();
                    xsdreader.Close();
                }
                catch (XmlException e)
                {
                    reader.Close();
                    xsdreader.Close();
                }
                nodeReader.Close();

                string html = "";
                if (OutputXmlFormat == true)
                {
                    html = "<?xml version=\"1.0\" encoding=\"utf-8\"?><root>" + ValidateError.ToString() + "</root>";
                }
                else
                {
                    html = ValidateError.ToString();
                }
                ValidateError.Remove(0, ValidateError.Length);
                return html;
            }
            public static string SchemaValidate(string XmlFile, string XsdFile)
            {
                return SchemaValidate(XmlFile, XsdFile, false);
            }
            public static string SchemaValidate(XmlDocument dom, string XsdFile)
            {
                return SchemaValidate(dom, XsdFile, false);
            }
            public static XmlDocument SchemaValidateOutputXml(string XmlFile, string XsdFile)
            {
                string xmlstr = SchemaValidate(XmlFile, XsdFile, true);
                XmlDocument dom = new XmlDocument();
                dom.LoadXml(xmlstr);
                return dom;
            }
            public static XmlDocument SchemaValidateOutputXml(XmlDocument dom, string XsdFile)
            {
                string xmlstr = SchemaValidate(dom, XsdFile, true);
                XmlDocument xmldom = new XmlDocument();
                xmldom.LoadXml(xmlstr);
                return xmldom;
            }
            private static void ValidationEventHandlerDetail(object sender, ValidationEventArgs args)
            {
                ValidateError.Append("<validateinfo>");
                ValidateError.Append("<severity>" + args.Severity + "</severity>");
                ValidateError.Append("<message>" + args.Message.Replace("<", "&lt;").Replace(">", "&gt;") + "</message>");
                ValidateError.Append("<line>" + args.Exception.LineNumber + "</line>");
                ValidateError.Append("<position>" + args.Exception.LinePosition + "</position>");
                ValidateError.Append("<source>" + args.Exception.SourceUri + "</source>");
                ValidateError.Append("</validateinfo>");
            }
            private static void ValidationEventHandlerMessage(object sender, ValidationEventArgs args)
            {
                ValidateError.Append("args.Message");
            }

            //public static string GetLangValue(string DictKey, string Lang)
            //{
            //    XmlDocument dom = GetLangDictionary(Lang);
            //    XmlNode Node = dom.SelectSingleNode("/root/key[@name='" + DictKey + "']");
            //    if (Node == null) return string.Empty;
            //    return Node.InnerText;
            //}

            //public static XmlDocument GetLangDictionary(string lang)
            //{
            //    if (string.IsNullOrEmpty(lang))
            //    {
            //        lang = "zh-cn";
            //    }
            //    string xmlfile = SBS.Base.GlobalCache.GetSiteConfig().SelectSingleNode("/root/xmldata").InnerText + "language\\" + lang + ".xml";

            //    XmlNode LangNode = SBS.Base.GlobalCache.GetSiteConfig().SelectSingleNode("/root/language/lang[@name='" + lang + "']");
            //    if (LangNode == null)
            //    {
            //        XmlDocument empty = new XmlDocument();
            //        empty.LoadXml("<root/>");
            //        return empty;
            //    }


            //    if (!File.Exists(xmlfile))
            //    {
            //        XmlDocument empty = new XmlDocument();
            //        empty.LoadXml("<root/>");
            //        return empty;

            //    }
            //    if (HttpRuntime.Cache[xmlfile] != null)
            //    {
            //        return (XmlDocument)HttpRuntime.Cache[xmlfile];
            //    }

            //    XmlDocument dom = new XmlDocument();
            //    dom.Load(xmlfile);

            //    System.Web.Caching.CacheDependency dep = new System.Web.Caching.CacheDependency(xmlfile);
            //    HttpRuntime.Cache.Insert(xmlfile, dom, dep, System.DateTime.Now.AddHours(12), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, new System.Web.Caching.CacheItemRemovedCallback(SBS.Base.GlobalCache.CacheRemovedCallBack));
            //    return (XmlDocument)HttpRuntime.Cache[xmlfile];
            //}

            /// <summary>
            /// 分析路径，由左至右（由浅至深）递归创建目录，仅接受绝对路径。
            /// </summary>
            /// <param name="DirFullPath">完整的路径，如 c:\temp\abc</param>
            public static bool CreateDirectoryEx(string DirFullPath)
            {
                if (Directory.Exists(DirFullPath)) return false;
                if (DirFullPath.Contains(':') == false) return false;
                if (DirFullPath.Contains('\\') == false)
                {
                    if (DirFullPath.Contains("/") == false) return false;
                }
                string[] DirArr = DirFullPath.Split(new char[] { '/', '\\' });
                //StringBuilder Path = new StringBuilder(128);

                for (int i = 0; i < DirArr.Length; i++)
                {
                    if (string.IsNullOrEmpty(DirArr[i])) continue;
                    string path = string.Join(@"\", DirArr, 0, i + 1);
                    if (Directory.Exists(path)) continue;
                    if (path.EndsWith(":")) continue;
                    Directory.CreateDirectory(path);
                }
                return true;
                //下面需要验证，曾出错。
                //if (!DirFullPath.Contains('\\') || !DirFullPath.Contains(':')) return -1;
                //int Counter = 0;
                //string[] DirArr = DirFullPath.Split(new char[] { '/', '\\' });
                //for (int i = 0; i < DirArr.Length; i++)
                //{
                //    if (string.IsNullOrEmpty(DirArr[i])) continue;
                //    string path = string.Join(@"\", DirArr, 0, i + 1);
                //    if (Directory.Exists(path)) continue;
                //    Directory.CreateDirectory(path);
                //    Counter++;
                //}
                //return Counter;
            }

            public static void CompressContextOutput(HttpContext Context)
            {
                #region 压缩输出
                string acceptEncoding = Context.Request.Headers["Accept-Encoding"];
                if (!String.IsNullOrEmpty(acceptEncoding))
                {
                    if (acceptEncoding.Contains("gzip"))
                    {
                        Context.Response.AppendHeader("Content-encoding", "gzip");
                        Context.Response.Filter = new GZipStream(Context.Response.Filter, CompressionMode.Compress);
                    }
                    else if (acceptEncoding.Contains("deflate"))
                    {
                        Context.Response.AppendHeader("Content-encoding", "deflate");
                        Context.Response.Filter = new DeflateStream(Context.Response.Filter, CompressionMode.Compress);
                    }
                }
                #endregion
            }

            /// <summary>
            /// 取消Gzip 压缩输出，该方法是 CompressContextOutput 方法的逆向方法
            /// </summary>
            /// <param name="Context"></param>
            public static void UnCompressContextOutput(HttpContext Context)
            {
                Context.Response.Headers.Remove("Content-encoding");
                Context.Response.Filter = null;
            }

            public static void CompressContextOutput()
            {
                CompressContextOutput(HttpContext.Current);
            }

            /// <summary>
            /// 复制文件夹到指定的位置。SourceDir 下面所有的子目录、文件都将被复制到 TargetDir 位置下。
            /// </summary>
            /// <param name="SourceDir">源文件夹</param>
            /// <param name="TargetDir">目标位置</param>
            /// <param name="OverWrite">是否覆盖已存在的文件</param>
            public static void CopyDirecotry(string SourceDir, string TargetDir, bool OverWrite)
            {
                if (!SourceDir.EndsWith(@"\"))
                {
                    SourceDir += @"\";
                }
                if (!TargetDir.EndsWith(@"\"))
                {
                    TargetDir += @"\";
                }
                AppEntity.Common.Utility.CreateDirectoryEx(TargetDir);
                DirectoryInfo Src = new DirectoryInfo(SourceDir);
                FileInfo[] fs = Src.GetFiles("*", SearchOption.AllDirectories);
                int SrcLen = SourceDir.Length;

                foreach (FileInfo f in fs)
                {
                    string SrcFile = f.FullName;
                    string TarFile = TargetDir + f.FullName.Substring(SrcLen);
                    string Folder = TarFile.Substring(0, TarFile.LastIndexOf(@"\"));
                    AppEntity.Common.Utility.CreateDirectoryEx(Folder);
                    File.Copy(SrcFile, TarFile, OverWrite);
                }
            }

            /// <summary>
            /// 把Url字符串中的查询部分转换为字典。该方法有反向方法：DictionaryToQueryString
            /// </summary>
            /// <param name="uri"></param>
            /// <returns></returns>
            public static Dictionary<string, string> QueryStringToDictionary(string Url)
            {
                if (string.IsNullOrEmpty(Url)) return null;

                if (Url.StartsWith("/"))
                {
                    Url = Url.Substring(1);
                }
                if (Url.StartsWith("?"))
                {
                    Url = Url.Substring(1);
                }
                if (Url.Contains("?"))
                {
                    Url = Url.Substring(Url.IndexOf("?") + 1);
                }

                Dictionary<string, string> Arr = new Dictionary<string, string>();

                if (Url.Contains("&") == false)
                {
                    if (Url.Contains("="))
                    {
                        Arr.Add(Url.Substring(0, Url.IndexOf("=")), Url.Substring(Url.IndexOf("=") + 1));
                    }
                    else
                    {
                        Arr.Add(Url, null);
                    }
                    return Arr;
                }

                string[] KeyValue = Url.Split('&');
                foreach (string Key in KeyValue)
                {
                    if (Key.Contains("="))
                    {
                        Arr.Add(Key.Substring(0, Key.IndexOf("=")), Key.Substring(Key.IndexOf("=") + 1));
                    }
                    else
                    {
                        Arr.Add(Key, null);
                    }
                }
                return Arr;
            }

            /// <summary>
            /// 把字符串字典用 & 符合连接为 url 形式的 QueryString。该方法有反向方法：QueryStringToDictionary
            /// </summary>
            /// <param name="Dict"></param>
            /// <returns></returns>
            public static string DictionaryToQueryString(Dictionary<string, string> Dict)
            {
                List<string> Arr = new List<string>();
                Dict.Each(n => Arr.Add("{0}={1}".FormatString(n.Key, n.Value)));
                return Arr.ToArray().Join("&");
            }

            /// <summary>
            /// 从指定文件中读取所有行到 List，内部使用 FileStream
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <param name="Line">指定行内容</param>
            /// <param name="Comparison">StringComparison</param>
            /// <returns></returns>
            public static bool TxtFileExistsLine(string FileFullName, string Line, StringComparison Comparison)
            {
                if (!File.Exists(FileFullName)) return false;
                bool status = false;
                FileStream Fs = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader Reader = new StreamReader(Fs);
                while (!Reader.EndOfStream)
                {
                    if (Line.Equals(Reader.ReadLine(), Comparison))
                    {
                        status = true;
                        break;
                    }
                }
                Reader.Close();
                Fs.Close();
                return status;
            }
            /// <summary>
            /// 判断指定文件与 Lines 数组是否存在交集（文件中的某行存在于数组中）
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <param name="Lines"></param>
            /// <returns></returns>
            public static bool TxtFileExistsLine(string FileFullName, string[] Lines)
            {
                HashSet<string> LinesTable = new HashSet<string>();
                foreach (string Line in Lines)
                {
                    LinesTable.Add(Line);
                }
                if (!File.Exists(FileFullName)) return false;
                bool status = false;
                FileStream Fs = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader Reader = new StreamReader(Fs);
                while (!Reader.EndOfStream)
                {
                    if (LinesTable.Contains(Reader.ReadLine()))
                    {
                        status = true;
                        break;
                    }
                }
                Reader.Close();
                Fs.Close();
                return status;
            }
            /// <summary>
            /// 判断文件是否存在等于 Line 的行
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <param name="Line"></param>
            /// <returns></returns>
            public static bool TxtFileExistsLine(string FileFullName, string Line)
            {
                if (!File.Exists(FileFullName)) return false;
                bool status = false;
                FileStream Fs = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader Reader = new StreamReader(Fs);
                while (!Reader.EndOfStream)
                {
                    if (Line.Equals(Reader.ReadLine()))
                    {
                        status = true;
                        break;
                    }
                }
                Reader.Close();
                Fs.Close();
                return status;
            }
            /// <summary>
            /// 从指定文件中读取所有行到 List，内部使用 FileStream
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <returns>如果文件不存在，返回 null</returns>
            public static List<string> TxtFileReadLines(string FileFullName)
            {
                if (!File.Exists(FileFullName)) return null;
                List<string> Arr = new List<string>();
                FileStream Fs = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader Reader = new StreamReader(Fs);
                while (!Reader.EndOfStream)
                {
                    Arr.Add(Reader.ReadLine());
                }
                Reader.Close();
                Fs.Close();
                return Arr;
            }
            /// <summary>
            /// 删除文件指定行。内部使用 FileStream 读写锁。该方法不改变原文件的编码。
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <param name="Line">指定行的内容</param>
            /// <returns>如果文件不存在或没有发现指定行，返回 false，发现并删除，返回true</returns>
            public static bool TxtFileRemoveLine(string FileFullName, string Line)
            {
                if (!File.Exists(FileFullName)) return false;
                List<string> Arr = TxtFileReadLines(FileFullName);
                bool Status = false;
                foreach (string id in Arr)
                {
                    if (id.Equals(Line))
                    {
                        Status = true;
                        break;
                    }
                }
                if (Status == false) return false;
                Encoding Enc = GetEncoding(FileFullName);
                FileStream Fs = new FileStream(FileFullName, FileMode.Create, FileAccess.Write, FileShare.Read);
                StreamWriter Writer = new StreamWriter(Fs, Enc);
                foreach (string id in Arr)
                {
                    if (id.Equals(Line)) continue;
                    Writer.WriteLine(id);
                }
                Writer.Close();
                Fs.Close();
                return true;
            }

            /// <summary>
            /// 续加多行到文件结尾处。如果文件不存在，则新创建。
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <param name="Lines">多行</param>
            /// <param name="ExitIfLineExists">默认为 false。如果传入的 Line 已经存在于文件中，ExitIfLineExists 为 true 时，不再添加 Line 到文件，否则重复添加 Line。</param>
            /// <returns>添加成功返回 true， 否则为 false。</returns>
            public static bool TxtFileAppendLine(string FileFullName, string[] Lines, bool ExitIfLineExists)
            {
                if (ExitIfLineExists == true && TxtFileExistsLine(FileFullName, Lines) == true)
                {
                    return false;
                }

                FileStream Fs = new FileStream(FileFullName, FileMode.Append, FileAccess.Write, FileShare.None);
                StreamWriter Writer = new StreamWriter(Fs);
                foreach (string Line in Lines)
                {
                    Writer.WriteLine(Line);
                }
                Writer.Close();
                Fs.Close();
                return true;
            }
            public static bool TxtFileAppendLine(string FileFullName, string Line, bool ExitIfLineExists)
            {
                if (ExitIfLineExists == true && TxtFileExistsLine(FileFullName, Line) == true)
                {
                    return false;
                }

                FileStream Fs = new FileStream(FileFullName, FileMode.Append, FileAccess.Write, FileShare.None);
                StreamWriter Writer = new StreamWriter(Fs);
                Writer.WriteLine(Line);
                Writer.Close();
                Fs.Close();
                return true;
            }
            /// <summary>
            /// 续加新行到文件结尾处。如果文件不存在，则新创建。
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <param name="Line"></param>
            /// <returns></returns>
            public static bool TxtFileAppendLine(string FileFullName, string Line)
            {
                return TxtFileAppendLine(FileFullName, new string[] { Line }, false);
            }
            public static bool TxtFileAppendLine(string FileFullName, string[] Lines)
            {
                return TxtFileAppendLine(FileFullName, Lines, false);
            }
            public static void TxtFileClearContent(string FileFullName)
            {
                Encoding Enc = GetEncoding(FileFullName);
                FileStream Fs = new FileStream(FileFullName, FileMode.Create, FileAccess.Write, FileShare.Read);
                StreamWriter Writer = new StreamWriter(Fs, Enc);
                Writer.Close();
                Fs.Close();
            }
            /// <summary>
            /// 获取指定文件的编码
            /// </summary>
            /// <param name="FileFullName"></param>
            /// <returns></returns>
            public static System.Text.Encoding GetEncoding(string FileFullName)
            {
                FileStream fs = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                System.Text.Encoding Encoding = GetEncoding(fs);
                fs.Close();
                return Encoding;
            }
            /// <summary>
            /// 获取 Stream 的编码
            /// </summary>
            /// <param name="fs"></param>
            /// <returns></returns>
            public static System.Text.Encoding GetEncoding(Stream Stream)
            {
                /*byte[] Unicode=new byte[]{0xFF,0xFE};  
                byte[] UnicodeBIG=new byte[]{0xFE,0xFF};  
                byte[] UTF8=new byte[]{0xEF,0xBB,0xBF};*/

                BinaryReader r = new BinaryReader(Stream, System.Text.Encoding.Default);
                byte[] ss = r.ReadBytes(3);
                r.Close();
                //编码类型 Coding=编码类型.ASCII;   
                if (ss[0] >= 0xEF)
                {
                    if (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)
                    {
                        return System.Text.Encoding.UTF8;
                    }
                    else if (ss[0] == 0xFE && ss[1] == 0xFF)
                    {
                        return System.Text.Encoding.BigEndianUnicode;
                    }
                    else if (ss[0] == 0xFF && ss[1] == 0xFE)
                    {
                        return System.Text.Encoding.Unicode;
                    }
                    else
                    {
                        return System.Text.Encoding.Default;
                    }
                }
                else
                {
                    return System.Text.Encoding.Default;
                }
            }

            /// <summary>
            /// 测试动态编译C#代码
            /// </summary>
            /// <param name="Code">代码文本</param>
            /// <param name="NSClassName">类名，如果有命名空间，完整路径为：Namespace.ClassName</param>
            /// <returns></returns>
            public static string CompileCSharpCodeTest(string Code, string NSClassName)
            {
                CompilerParameters objCompilerParameters = new CompilerParameters();
                objCompilerParameters.ReferencedAssemblies.Add("System.dll");
                objCompilerParameters.ReferencedAssemblies.Add("System.Xml.dll");
                //objCompilerParameters.ReferencedAssemblies.Add("System.Xml.Linq.dll");
                objCompilerParameters.ReferencedAssemblies.Add("System.Web.dll");
                objCompilerParameters.ReferencedAssemblies.Add("mscorlib.dll");
                objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll");
                objCompilerParameters.ReferencedAssemblies.Add(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll");
                objCompilerParameters.ReferencedAssemblies.Add(HttpContext.Current.Server.MapPath("/") + @"\Bin\SBS.Common.dll");
                objCompilerParameters.ReferencedAssemblies.Add(HttpContext.Current.Server.MapPath("/") + @"\Bin\SBS.AppEntity.dll");
                objCompilerParameters.GenerateExecutable = false;
                objCompilerParameters.GenerateInMemory = true;

                CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }); ;
                CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, Code);
                StringBuilder sb = new StringBuilder();
                if (cr.Errors.HasErrors)
                {
                    foreach (CompilerError err in cr.Errors)
                    {
                        sb.AppendFormat("\r\n----------\r\nLine:{0}\r\nErrMsg:{1}", err.Line, err.ErrorText);
                    }
                    return sb.ToString();
                }

                // 通过反射，调用HelloWorld的实例
                try
                {
                    Assembly objAssembly = cr.CompiledAssembly;
                    object objHelloWorld = objAssembly.CreateInstance(NSClassName); //namespace+className
                }
                catch (Exception ex)
                {
                    throw new NullReferenceException(ex.Message);
                }
                //MethodInfo objMI = objHelloWorld.GetType().GetMethod("say");
                //object[] param = new object[] { "abc" };
                return string.Empty;
            }

            /// <summary>
            /// 动态编译C#代码
            /// </summary>
            /// <param name="Code">代码文本</param>
            /// <param name="NSClassName">类名，如果有命名空间，完整路径为：Namespace.ClassName</param>
            /// <returns></returns>
            public static object CompileCSharpCode(string Code, string NSClassName)
            {
                CompilerParameters objCompilerParameters = new CompilerParameters();
                objCompilerParameters.ReferencedAssemblies.Add("System.dll");
                objCompilerParameters.ReferencedAssemblies.Add("System.Xml.dll");
                objCompilerParameters.ReferencedAssemblies.Add("System.Web.dll");
                objCompilerParameters.ReferencedAssemblies.Add("mscorlib.dll");
                objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll");
                objCompilerParameters.ReferencedAssemblies.Add(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll");
                objCompilerParameters.ReferencedAssemblies.Add(HttpContext.Current.Server.MapPath("/") + @"\Bin\SBS.Common.dll");
                objCompilerParameters.ReferencedAssemblies.Add(HttpContext.Current.Server.MapPath("/") + @"\Bin\SBS.AppEntity.dll");
                objCompilerParameters.GenerateExecutable = false;
                objCompilerParameters.GenerateInMemory = true;

                CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }); ;
                CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, Code);
                StringBuilder sb = new StringBuilder();
                if (cr.Errors.HasErrors)
                {
                    return null;
                }
                try
                {
                    Assembly objAssembly = cr.CompiledAssembly;
                    object objHelloWorld = objAssembly.CreateInstance(NSClassName); //namespace+className
                    return objHelloWorld;
                }
                catch (Exception ex)
                {
                    throw new NullReferenceException(ex.Message);
                }
                //MethodInfo objMI = objHelloWorld.GetType().GetMethod("say");
                //object[] param = new object[] { "abc" };
                return null;
            }

            /// <summary>
            /// 随机生成0-9a-zA-Z的字符串，长度由传入的 Length 指定
            /// </summary>
            /// <param name="length"></param>
            /// <returns></returns>        
            public static string GenerateRandomKey(int length)
            {
                return new String(GenerateRandomArray("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(), length));
                //char[] result = new char[length];
                //string str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";            
                //for (int i = 0; i < length; i++)
                //{
                //    int index = Random.Next(62);
                //    result[i] = str[index];                
                //}
                //return new String(result);
            }
            /// <summary>
            /// 从数组中随机抽取出指定长度子数组
            /// </summary>
            /// <typeparam name="T">泛型</typeparam>
            /// <param name="Array">现有数组</param>
            /// <param name="n">指定新数组的长度</param>
            /// <returns></returns>
            public static T[] GenerateRandomArray<T>(T[] Array, int n)
            {
                int Len = Array.Length;
                T[] result = new T[n];
                for (int i = 0; i < n; i++)
                {
                    int index = Random.Next(Len);
                    result[i] = Array[index];
                }
                return result;
            }
        }
    }
}
